package com.zhx.common.chat.consumer;


import cn.hutool.core.util.ObjectUtil;
import com.zhx.common.chat.dao.ContactDao;
import com.zhx.common.chat.dao.MessageDao;
import com.zhx.common.chat.dao.RoomDao;
import com.zhx.common.chat.dao.RoomFriendDao;
import com.zhx.common.chat.domain.entity.Message;
import com.zhx.common.chat.domain.entity.Room;
import com.zhx.common.chat.domain.entity.RoomFriend;
import com.zhx.common.chat.domain.enums.RoomTypeEnum;
import com.zhx.common.chat.domain.vo.response.ChatMessageResp;
import com.zhx.common.chat.service.ChatService;
import com.zhx.common.chat.service.cache.GroupMemberCache;
import com.zhx.common.chat.service.cache.HotRoomCache;
import com.zhx.common.chat.service.cache.RoomCache;
import com.zhx.common.common.constant.MQConstant;
import com.zhx.common.common.domain.dto.MsgSendMessageDTO;
import com.zhx.common.user.service.adapter.WSAdapter;
import com.zhx.common.user.service.impl.PushService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

@Component
@Slf4j
@RocketMQMessageListener(consumerGroup = MQConstant.SEND_MSG_GROUP, topic = MQConstant.SEND_MSG_TOPIC)
public class MsgSendConsumer implements RocketMQListener<MsgSendMessageDTO> {

    @Resource
    private MessageDao messageDao;
    @Resource
    private RoomCache roomCache;
    @Resource
    private ChatService chatService;
    @Resource
    private RoomDao roomDao;
    @Resource
    private HotRoomCache hotRoomCache;
    @Resource
    private PushService pushService;
    @Resource
    private RoomFriendDao roomFriendDao;
    @Resource
    private GroupMemberCache groupMemberCache;
    @Resource
    private ContactDao contactDao;

    /**
     * 当接收到消息时的处理逻辑。
     *
     * @param dto 消息发送的DTO，包含消息ID等信息。
     * 主要逻辑包括：
     * 1. 通过消息ID获取消息对象。
     * 2. 通过消息获取对应的房间，并从缓存中删除该房间。
     * 3. 根据消息，生成聊天消息响应对象。
     * 4. 更新房间的活跃时间，并从缓存中删除该房间。
     * 5. 如果房间是热门房间，则更新热门房间的活跃时间，并推送消息给所有在线用户。
     * 6. 如果房间不是热门房间，则根据房间类型推送消息给相应的用户群体（群聊则推送给所有群成员，单聊则推送给指定两人）。
     */
    @Override
    public void onMessage(MsgSendMessageDTO dto) {
        if(ObjectUtil.isEmpty(dto)){
            log.error("消息为空");
            return;
        }
        log.info("收到消息：{}", dto);
        // 根据消息ID获取消息
        Message message = messageDao.getById(dto.getMsgId());
        // 根据消息获取房间，并从缓存中删除该房间
        Room room = roomCache.get(message.getRoomId());
        // 生成聊天消息响应对象
        ChatMessageResp msgResp = chatService.getMsgResp(message, null);

        // 更新房间活跃时间和消息时间
        roomDao.refreshActiveTime(room.getId(), message.getId(), message.getCreateTime());
        // 从缓存中删除房间
        roomCache.delete(room.getId());

        if (room.isHotRoom()) {
            // 如果是热门房间，更新热门房间活跃时间并推送消息给所有在线用户
            hotRoomCache.refreshActiveTime(room.getId(), message.getCreateTime());
            pushService.sendPushMsg(WSAdapter.buildMsgSend(msgResp));
        } else {
            // 根据房间类型收集需要推送消息的用户ID列表
            List<Long> memberUidList = new ArrayList<>();
            // 如果是群聊，收集群成员ID列表
            if (Objects.equals(room.getType(), RoomTypeEnum.GROUP.getType())) {
                memberUidList = groupMemberCache.getMemberUidList(room.getId());
                // 如果是单聊，收集双方ID
            } else if (Objects.equals(room.getType(), RoomTypeEnum.FRIEND.getType())) {
                RoomFriend roomFriend = roomFriendDao.getByRoomId(room.getId());
                memberUidList = Arrays.asList(roomFriend.getUid1(), roomFriend.getUid2());
            }
            // 更新群成员会话活跃时间并推送消息
            contactDao.refreshOrCreateActiveTime(room.getId(), memberUidList, message.getId(), message.getCreateTime());
            pushService.sendPushMsg(WSAdapter.buildMsgSend(msgResp), memberUidList);
        }
    }

}
